package core

import (
	"context"
	"encoding/json"
	"ez/apps/core/auto/mc"
	"gitee.com/dreamwood/ez-go/db/mgo"
	"gitee.com/dreamwood/ez-go/ez"
	"gitee.com/dreamwood/ez-go/ss"
	"time"
)

type Role struct {
	mgo.BaseDoc   `bson:"-" json:"-"`
	Id            int64      `json:"id" bson:"id,omitempty"`
	Name          string     `json:"name" bson:"name"`                   //角色名
	Code          string     `json:"code" bson:"code"`                   //编码
	Model         []*Model   `json:"model" bson:"model"`                 //可用模块
	ModelIds      []int64    `json:"modelIds" bson:"modelIds"`           //可用模块
	Top           []*Top     `json:"top" bson:"top"`                     //顶栏权限
	TopIds        []int64    `json:"topIds" bson:"topIds"`               //顶栏权限
	Menu          []*Menu    `json:"menu" bson:"menu"`                   //菜单权限
	MenuIds       []int64    `json:"menuIds" bson:"menuIds"`             //菜单权限
	ApiAllow      []*Api     `json:"apiAllow" bson:"apiAllow"`           //放通接口权限
	ApiAllowIds   []int64    `json:"apiAllowIds" bson:"apiAllowIds"`     //放通接口权限
	ApiDeny       []*Api     `json:"apiDeny" bson:"apiDeny"`             //禁止接口权限
	ApiDenyIds    []int64    `json:"apiDenyIds" bson:"apiDenyIds"`       //禁止接口权限
	ApiAllowKeys  []string   `json:"apiAllowKeys" bson:"apiAllowKeys"`   //禁止接口权限
	ApiDenyKeys   []string   `json:"apiDenyKeys" bson:"apiDenyKeys"`     //禁止接口权限
	Page          []*Page    `json:"page" bson:"page"`                   //页面权限
	PageIds       []int64    `json:"pageIds" bson:"pageIds"`             //页面权限
	PageAllowKeys []string   `json:"pageAllowKeys" bson:"pageAllowKeys"` //页面放行权限
	PageDenyKeys  []string   `json:"pageDenyKeys" bson:"pageDenyKeys"`   //页面禁止权限
	CreateAt      time.Time  `json:"createAt" bson:"createAt"`
	UpdateAt      time.Time  `json:"updateAt" bson:"updateAt"`
	DeleteAt      *time.Time `json:"deleteAt" bson:"deleteAt"`
}

func (this *Role) DocName() string { return "Role" }
func (this *Role) GetId() int64    { return this.Id }
func (this *Role) SetId(id int64)  { this.Id = id }
func (this *Role) Create() error {
	return this.GetFactory().Create(this)
}
func (this *Role) Replace() error {
	return this.GetFactory().Replace(this)
}
func (this *Role) Save() error {
	if this.Id == 0 {
		this.CreateAt = time.Now()
		this.UpdateAt = time.Now()
		return this.GetFactory().Create(this)
	} else {
		this.UpdateAt = time.Now()
		return this.GetFactory().Replace(this)
	}
}

// 伪删除
func (this *Role) Delete() error {
	return this.GetFactory().Delete(this)
}
func (this *Role) UnDelete() error {
	return this.GetFactory().UnDelete(this)
}

// 真删除
func (this *Role) Destroy() error {
	return this.GetFactory().Destroy(this)
}
func (this *Role) ToString() string {
	return string(this.ToBytes())
}
func (this *Role) ToBytes() []byte {
	data, e := json.Marshal(this)
	ez.Try(e)
	return data
}
func (this *Role) Serialize() []byte {
	data, e := json.Marshal(this)
	ez.Try(e)
	return data
}
func (this *Role) UnSerialize(data []byte) []byte {
	ez.Try(json.Unmarshal(data, this))
	return data
}
func (this *Role) LoadModel() {
	if this.Model == nil {
		this.Model = make([]*Model, 0)
	}
	if this.ModelIds == nil {
		this.ModelIds = make([]int64, 0)
	}
	if len(this.ModelIds) > 0 {
		this.Model = make([]*Model, 0)
		for _, v := range this.ModelIds {
			find, e := NewModelCrud().FindId(v)
			if e == nil {
				this.Model = append(this.Model, find)
			}
		}
	}
}
func (this *Role) LoadTop() {
	if this.Top == nil {
		this.Top = make([]*Top, 0)
	}
	if this.TopIds == nil {
		this.TopIds = make([]int64, 0)
	}
	if len(this.TopIds) > 0 {
		this.Top = make([]*Top, 0)
		for _, v := range this.TopIds {
			find, e := NewTopCrud().FindId(v)
			if e == nil {
				this.Top = append(this.Top, find)
			}
		}
	}
}
func (this *Role) LoadMenu() {
	if this.Menu == nil {
		this.Menu = make([]*Menu, 0)
	}
	if this.MenuIds == nil {
		this.MenuIds = make([]int64, 0)
	}
	if len(this.MenuIds) > 0 {
		this.Menu = make([]*Menu, 0)
		for _, v := range this.MenuIds {
			find, e := NewMenuCrud().FindId(v)
			if e == nil {
				this.Menu = append(this.Menu, find)
			}
		}
	}
}
func (this *Role) LoadApiAllow() {
	if this.ApiAllow == nil {
		this.ApiAllow = make([]*Api, 0)
	}
	if this.ApiAllowIds == nil {
		this.ApiAllowIds = make([]int64, 0)
	}
	if len(this.ApiAllowIds) > 0 {
		this.ApiAllow = make([]*Api, 0)
		for _, v := range this.ApiAllowIds {
			find, e := NewApiCrud().FindId(v)
			if e == nil {
				this.ApiAllow = append(this.ApiAllow, find)
			}
		}
	}
}
func (this *Role) LoadApiDeny() {
	if this.ApiDeny == nil {
		this.ApiDeny = make([]*Api, 0)
	}
	if this.ApiDenyIds == nil {
		this.ApiDenyIds = make([]int64, 0)
	}
	if len(this.ApiDenyIds) > 0 {
		this.ApiDeny = make([]*Api, 0)
		for _, v := range this.ApiDenyIds {
			find, e := NewApiCrud().FindId(v)
			if e == nil {
				this.ApiDeny = append(this.ApiDeny, find)
			}
		}
	}
}
func (this *Role) LoadPage() {
	if this.Page == nil {
		this.Page = make([]*Page, 0)
	}
	if this.PageIds == nil {
		this.PageIds = make([]int64, 0)
	}
	if len(this.PageIds) > 0 {
		this.Page = make([]*Page, 0)
		for _, v := range this.PageIds {
			find, e := NewPageCrud().FindId(v)
			if e == nil {
				this.Page = append(this.Page, find)
			}
		}
	}
}
func (this *Role) ClearRelationsBeforeSave() mgo.Doc {
	this.Model = nil
	this.Top = nil
	this.Menu = nil
	this.ApiAllow = nil
	this.ApiDeny = nil
	this.Page = nil
	return this
}
func neverUsed_Role() {
	//导入ss包
	a := ss.M{}
	ez.Debug(a)
}

type RoleAccessControl struct {
	Access  bool
	Message string
	Action  string //控制器Action,小写开头，如c,u,r,d
	Model   *Role
	Session *ez.Session
}

func NewRoleAccessControl(model *Role, action string, session *ez.Session) *RoleAccessControl {
	ctrl := &RoleAccessControl{
		Access:  true,
		Model:   model,
		Action:  action,
		Session: session,
	}
	ez.DispatchToMany(mc.RoleAccessControlEvent, ctrl, context.TODO())
	return ctrl
}
